import localforage from "localforage";
import { Initer, makeStore, Reducer } from "../utils/makeStore";
const defaultValue = {
  sesame: false,
  sesame2: false,
  session_id: '',
  user_id: 0,
  username: '',
  admin: 0,
  site_name: '',
  site_breif: '',
  is_me: false,
  sts: {
    accessKeyId: '',
    accessKeySecret: '',
    expiration: '',
    securityToken: ''
  },
  async_count: 0
}
export type Value = typeof defaultValue
export interface TypePayloadMap {
  "sesame": boolean,
  "logout": null,
  "login": Pick<Value, 'session_id' | 'username' | 'admin'>,
  "user_info": Pick<Value, 'username' | 'admin' | 'user_id'>,
  "site_info": Pick<Value, 'site_name' | 'site_breif' | 'is_me'>,
  "sts_info": Value['sts'],
  "sesame2": boolean,
}
export type Actions =
  { type: "sesame", payload: TypePayloadMap["sesame"] } |
  { type: "sesame2", payload: TypePayloadMap["sesame2"] } |
  { type: "logout", payload: TypePayloadMap["logout"] } |
  { type: "login", payload: TypePayloadMap["login"] } |
  { type: "user_info", payload: TypePayloadMap["user_info"] } |
  { type: "site_info", payload: TypePayloadMap["site_info"] } |
  { type: "sts_info", payload: TypePayloadMap["sts_info"] } |
  { type: "async_count" }

const reducer: Reducer<Value, Actions> = async (state, action) => {
  switch (action.type) {
    case 'sesame':
      await localforage.setItem('sesame', action.payload)
      return { ...state, sesame: action.payload }
    case 'sesame2':
      await localforage.setItem('sesame2', action.payload)
      return { ...state, sesame2: action.payload }
    case "logout":
      await localforage.removeItem('session_id')
      await localforage.removeItem('username')
      await localforage.removeItem('admin')
      await localforage.removeItem('user_id')
      const { site_breif, site_name, sesame } = state;
      return { ...defaultValue, site_breif, site_name, sesame }
    case "login":
      await localforage.setItem('session_id', action.payload.session_id)
      return { ...state, ...action.payload }
    case "user_info":
      await localforage.setItem('username', action.payload.username)
      await localforage.setItem('admin', action.payload.admin)
      await localforage.setItem('user_id', action.payload.user_id)
      return { ...state, ...action.payload }
    case "site_info":
      await localforage.setItem('site_name', action.payload.site_name)
      await localforage.setItem('site_breif', action.payload.site_breif)
      return { ...state, ...action.payload }
    case "sts_info":
      await localforage.setItem('sts', action.payload)
      return { ...state, sts: action.payload }
    case "async_count":
      await new Promise(a => setTimeout(a, 100));
      return { ...state, async_count: state.async_count + 1 }
  }
  return state
}
const initer: Initer<Value> = async () => {
  const ret = {
    sesame: await localforage.getItem<boolean>('sesame')
      .catch(_ => void 0).then(v => v ?? defaultValue.sesame),
    sesame2: await localforage.getItem<boolean>('sesame2')
      .catch(_ => void 0).then(v => v ?? defaultValue.sesame2),
    session_id: await localforage.getItem<string>('session_id')
      .catch(_ => void 0).then(v => v ?? defaultValue.session_id),
    username: await localforage.getItem<string>('username').catch(e => void 0).then(v => v ?? ''),
    user_id: await localforage.getItem<number>('user_id').catch(e => void 0).then(v => v ?? 0),
    admin: await localforage.getItem<number>('admin').catch(e => void 0).then(v => v ?? 0),
    site_name: await localforage.getItem<string>('site_name')
      .catch(_ => void 0).then(v => v || defaultValue.site_name),
    site_breif: await localforage.getItem<string>('site_breif')
      .catch(_ => void 0).then(v => v || defaultValue.site_breif),
    sts: await localforage.getItem<Value['sts']>('sts')
      .catch(_ => void 0).then(r => r || defaultValue.sts),
  }
  return ret;
}
export const GlobalStore = makeStore<Value, Actions>("GlobalStore", defaultValue, reducer, initer);